package com.norns.torque

import android.bluetooth.BluetoothAdapter
import android.os.Handler
import android.os.Looper
import androidx.collection.ArrayMap
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.norns.torque.bluetooth.ChatServer
import com.norns.torque.listener.BluetoothRssiListener
import com.norns.torque.listener.BluetoothStateListener
import com.norns.torque.listener.ConnectedListener
import com.norns.torque.listener.MessageListener
import com.norns.torque.socket.ClientSocket
import com.norns.torque.utils.AppConstant
import com.norns.torque.utils.DataConversion
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber

class BluetoothViewModel : ViewModel() {
    private val optionsStr = ArrayMap<Int, String>()

    private val _messages = MutableLiveData<String>()
    val messages = _messages as LiveData<String>

    private val _bluetoothRssi = MutableLiveData<Int>()
    val bluetoothRssi = _bluetoothRssi as LiveData<Int>

    private val _connectionState = MutableLiveData<Int>()
    val connectionState = _connectionState as LiveData<Int>
    //蓝牙开关状态
    private val _bluetoothState = MutableLiveData<Int>()
    val bluetoothState = _bluetoothState as LiveData<Int>

    companion object{
       const val checkResultMessage = 1908
    }
    private var isResultMessage:Boolean=false
    private var resultMessageCount:Int=0

    private val handler: Handler = object : Handler(Looper.myLooper()!!) {
        override fun handleMessage(msg: android.os.Message) {
            if (checkResultMessage == msg.what) {
                if (resultMessageCount>5){
                    disconnect()
                    _connectionState.postValue(AppConstant.connectionField)
                }else{
                    if (!isResultMessage&&isConnected()) {
                        readDeviceValue()
                    }
                }

            }
        }
    }
    private val connectedListener:ConnectedListener
    private val messageListener:MessageListener
    private val rssiListener: BluetoothRssiListener
    private val bluetoothStateListener: BluetoothStateListener
    init {
        optionsStr[0] = "N.m"
        optionsStr[1] = "Ibf.ft"
        optionsStr[2] = "Ibf.in"
        optionsStr[3] = "kgf.cm"
        optionsStr[4] = "kgf.m"
        connectedListener= object:ConnectedListener{
            override fun onConnected(connectedState: Int) {
                _connectionState.postValue(connectedState)
            }
        }
        messageListener= object : MessageListener{
            override fun onMessage(message: String) {
                addMessage("接收到设备返回的数据:${message}")
                _messages.postValue(message)
            }

        }
        rssiListener = object :BluetoothRssiListener{
            override fun onRssi(rssi: Int) {
                _bluetoothRssi.postValue(rssi)
            }
        }
        bluetoothStateListener = object :BluetoothStateListener{
            override fun onState(bluetoothState: Int) {
                _bluetoothState.value=bluetoothState
            }
        }
        initLister()
    }
    fun setResultMessageState(state:Boolean){
        isResultMessage=state
        resultMessageCount=0
    }

    //读取设备设置值
    fun readDeviceValue() {
        isResultMessage=false
        resultMessageCount+=1
        Timber.i("读取设备设置值")
        addMessage("读取设备设置值")
        writeIntDataCommand(0xFF, 0)
        handler.removeMessages(checkResultMessage)
        handler.sendEmptyMessageDelayed(checkResultMessage,1000)
    }
    private fun addMessage(message:String){
        ChatServer.addMessage(message)
    }
    //设置目标值
    fun setTargetValue(value: Int) {
        Timber.i("设置设备目标值 ${value}")
        addMessage("设置设备目标值 ${value}")
        writeIntDataCommand(1, value)
    }

    //设置精度值
    fun setPrecisionValue(value: Int) {
        Timber.i("设置设备精度值 ${value}")
        addMessage("设置设备精度值 ${value}")
        writeIntDataCommand(2, value)
    }

    //设置单位
    fun setUnitValue(value: Int) {
        Timber.i("设置设备单位值 ${value}")
       addMessage("设置设备单位值 ${value}")
        writeIntDataCommand(3, value)
    }

    //恢复出厂设置
    fun setResetValue() {
        Timber.i("恢复设备出厂设置: AA550700070D0A")
       addMessage("恢复设备出厂设置")
       addMessage("AA550700070D0A")
        val byteArray = DataConversion.hexStringToByteArray("AA550700070D0A")
        if (ChatServer.NetWork == ChatServer.contentType) {
            writeMsgInternal(byteArray)
        } else {
            ChatServer.sendByteArrayMessage(byteArray)
        }
    }

    //设置蓝牙名称
    fun setRenameValue(value: String) {
        val stringBuilder=DataConversion.originalStringToHexString(value)
        Timber.i("设置设备蓝牙名称: hexString=${stringBuilder}  value=${value}")
        addMessage("设置设备蓝牙名称 hexString=${stringBuilder}  value=${value}")
        //val str=DataConversion.hexStringToOriginalString(stringBuilder)
        //Timber.i("设置设备蓝牙名称: text=${str}")
        writeHexDataCommand(6, stringBuilder)
    }

    //设置时间值
    fun setTimeValue(value: String) {
        Timber.i("设置设备时间值: time = ${value}")
        writeHexDataCommand(0x05, value)
    }

    //设置日期值
    fun setDateValue(value: String) {
        Timber.i("设置设备日期值: data = ${value}")
       addMessage("设置设备日期值 data = ${value}")
        writeHexDataCommand(0x04, value)
    }

    //设置wifi密码
    fun setWiFiAndPwd(wifi: String, pwd: String) {
        val wifiByteArray = wifi.toByteArray()
        val pwdByteArray = pwd.toByteArray()
        val stringBuilder = StringBuilder()
        for (w :Byte in wifiByteArray) {
            val hexString = DataConversion.intToHex(w)
            stringBuilder.append(hexString)
        }
        stringBuilder.append("00")
        for (p in pwdByteArray) {
            val hexString = DataConversion.intToHex(p)
            stringBuilder.append(hexString)
        }
        stringBuilder.append("00")
        Timber.i("设置设备WiFi名称: hexString=${stringBuilder}  wifi=${wifi} pwd=${pwd}")
       addMessage("设置设备WiFi名称: hexString=${stringBuilder}  wifi=${wifi} pwd=${pwd}")
        writeHexDataCommand(0x0A, stringBuilder.toString())
    }

    fun getUnitString(index: Int): String? {
        return optionsStr[index]
    }

    //获取Track值
    fun getTrackValue() {
        Timber.i("获取设备Track值")
        addMessage("获取设备Track值")
        writeIntDataCommand(8, 0)
    }

    //打开自动上传
    fun openAutoPeak() {
        Timber.i("打开设备自动上传")
       addMessage("打开设备自动上传")
        writeIntDataCommand(9, 1)
    }

    //关闭自动上传
    fun closeAutoPeak() {
        Timber.i("关闭设备自动上传")
       addMessage("打开设备自动上传")
        writeIntDataCommand(9, 0)
    }

    private fun writeIntDataCommand(registerAddr: Int, registerValue: Int) {
        val hexString = DataConversion.intToHex(registerValue)
        val byteArray = DataConversion.hexStringToByteArray(hexString)
        //Timber.d( "设置目标值:${byteArray[0]}--${byteArray[1]}--${byteArray[2]}--${byteArray[3]}")
        val sendContent = DataConversion.makeWriteRegDataCommand(registerAddr, byteArray)
        if (ChatServer.NetWork == ChatServer.contentType) {
            writeMsgInternal(sendContent)
        } else {
            ChatServer.sendByteArrayMessage(sendContent)
        }
        val codeStr = DataConversion.encodeHexString(sendContent)
        addMessage(codeStr)
        Timber.d("     向设备发送数据: ${codeStr} -- ${registerValue}")
    }

    private fun writeHexDataCommand(registerAddr: Int, hexString: String) {
        val byteArray = DataConversion.hexStringToByteArray(hexString)
        //Timber.d( "设置目标值:${byteArray[0]}--${byteArray[1]}--${byteArray[2]}--${byteArray[3]}")
        val sendContent = DataConversion.makeWriteRegDataCommand(registerAddr, byteArray)
        if (ChatServer.NetWork == ChatServer.contentType) {
            writeMsgInternal(sendContent)
        } else {
            ChatServer.sendByteArrayMessage(sendContent)
        }
        val codeStr = DataConversion.encodeHexString(sendContent)
        addMessage(codeStr)
        Timber.d("     向设备发送数据: ${codeStr}")
    }

    private fun writeMsgInternal(messageBytes: ByteArray) {
        viewModelScope.launch {
            withContext(Dispatchers.IO) {
                ClientSocket.writeMsgInternal(messageBytes)
            }
        }
    }
    fun stopGetDeviceRssi(){
        if (ChatServer.contentType==ChatServer.Bluetooth) {
            ChatServer.stopGetDeviceRssi()
        }
    }
    fun startGetDeviceRssi(){
        if (ChatServer.contentType==ChatServer.Bluetooth) {
            ChatServer.startGetDeviceRssi()
        }
    }

    fun isConnected():Boolean{
       return if (ChatServer.contentType==ChatServer.NetWork) {
            ClientSocket.isConnected
        }else{
           val bluetoothState = bluetoothState.value
            ChatServer.connectedState==AppConstant.connectionSuccess&& bluetoothState != BluetoothAdapter.STATE_OFF
        }
    }

    private fun initLister(){
        if (ChatServer.contentType==ChatServer.NetWork) {
            initSocketListener()
        }else{
            initBluetoothListener()
        }
    }

    private fun initBluetoothListener(){
        ChatServer.addConnectionListener(connectedListener)
        ChatServer.addBluetoothStateListener(bluetoothStateListener)
        //rssi
        ChatServer.addBluetoothRssiListener(rssiListener)
        ChatServer.addMessagesListener(messageListener)
    }
    private fun initSocketListener(){
        ClientSocket.addConnectionListener(connectedListener)
        ClientSocket.addMessagesListener(messageListener)
    }

    fun removeListener(){
        if (ChatServer.contentType==ChatServer.NetWork) {
            ClientSocket.removeMessagesListener(messageListener)
            ClientSocket.removeConnectionListener(connectedListener)
        }else{
            ChatServer.removeMessagesListener(messageListener)
            ChatServer.removeConnectionListener(connectedListener)
            ChatServer.removeBluetoothStateListener(bluetoothStateListener)
            //rssi
            ChatServer.removeBluetoothRssiListener(rssiListener)
        }
    }


    fun disconnect(){
        removeListener()
        if (ChatServer.contentType==ChatServer.NetWork) {
            ClientSocket.close()
        }else{
            ChatServer.disconnect()
        }
    }
    fun testcmd(){
        viewModelScope.launch(Dispatchers.IO) {
            val message="AA44FF1101F401F30400 241015 155740 7378353030 720D0A000000000000000000000000000000000000000000000"
            _messages.postValue(message)
        }
    }

    override fun onCleared() {
        resultMessageCount=0
        removeListener()
        handler.removeCallbacksAndMessages(null)
        super.onCleared()
    }


}